Java.lang প্যাকেজটি Java এর একটি গুরুত্বপূর্ণ এবং স্বয়ংক্রিয়ভাবে লোড হওয়া প্যাকেজ, যা Java প্রোগ্রামের মূল ফিচার এবং ক্লাসের সমর্থন দেয়। এই প্যাকেজে Java এর সমস্ত ক্লাসের জন্য বেস ক্লাস java.lang.Object রয়েছে।
Object ক্লাস হল Java-তে সমস্ত ক্লাসের সুপারক্লাস (Superclass) এবং প্রতিটি ক্লাসের জন্য ডিফল্ট বেস ক্লাস হিসেবে কাজ করে। অর্থাৎ, আপনি যদি কোনো নতুন ক্লাস তৈরি করেন, তবে তা সরাসরি বা পরোক্ষভাবে Object ক্লাস থেকে ইনহেরিট করবে।
Object ক্লাসের গুরুত্বপূর্ণ বৈশিষ্ট্য:
- Superclass for all Java Classes:
Objectক্লাস Java-তে সমস্ত ক্লাসের সুপারক্লাস। যেহেতু সমস্ত ক্লাসObjectক্লাস থেকে ইনহেরিট করে, তাইObjectক্লাসে থাকা মেথডগুলি প্রতিটি ক্লাসের জন্য উপলব্ধ থাকে।
- মেথড সমূহ:
Objectক্লাস অনেক গুরুত্বপূর্ণ মেথড প্রদান করে, যেগুলি Java প্রোগ্রামের মধ্যে সাধারণ কাজ সম্পাদন করতে সহায়তা করে। এখানে কিছু গুরুত্বপূর্ণ মেথড দেওয়া হলো:toString():- এই মেথডটি একটি অবজেক্টের স্ট্রিং রূপ (string representation) প্রদান করে। যদি কোনো ক্লাসে এই মেথডটি ওভাররাইড করা না হয়, তবে ডিফল্টভাবে এটি অবজেক্টের ক্লাসের নাম এবং হ্যাশ কোড প্রদান করবে।
উদাহরণ:
class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Name: " + name + ", Age: " + age; } } public class Main { public static void main(String[] args) { Person p = new Person("John", 30); System.out.println(p.toString()); // Output: Name: John, Age: 30 } }
equals():equals()মেথড দুটি অবজেক্টের মধ্যে সমানতা যাচাই করে। ডিফল্টভাবে এটি অবজেক্টের রেফারেন্স সমান কিনা তা যাচাই করে। তবে সাধারণত এটি ক্লাসে ওভাররাইড করা হয় যাতে অবজেক্টের কন্টেন্ট বা মানের ভিত্তিতে সমানতা পরীক্ষা করা যায়।উদাহরণ:
class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; return age == person.age && name.equals(person.name); } } public class Main { public static void main(String[] args) { Person p1 = new Person("John", 30); Person p2 = new Person("John", 30); System.out.println(p1.equals(p2)); // Output: true } }
hashCode():hashCode()মেথড একটি অবজেক্টের হ্যাশ কোড প্রদান করে, যা সাধারণতequals()মেথডের সাথে সম্পর্কিত থাকে।hashCode()মেথডটি সমান অবজেক্টগুলির জন্য একই হ্যাশ কোড প্রদান করা উচিত। এটি কাস্টমequals()মেথডের সাথে সাধারণত একত্রে ওভাররাইড করা হয়।উদাহরণ:
class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int hashCode() { return name.hashCode() + age; } }
clone():clone()মেথড একটি অবজেক্টের শ্যালো কপি (shallow copy) তৈরি করে। এটিCloneableইন্টারফেসের সাথে সম্পর্কিত এবং ডিফল্টভাবে কেবল শ্যালো কপি তৈরি করে, অর্থাৎ অবজেক্টের গভীর কপি (deep copy) তৈরি করতে হলে কাস্টম কোড লিখতে হয়।উদাহরণ:
class Person implements Cloneable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person("John", 30); Person p2 = (Person) p1.clone(); System.out.println(p1 == p2); // Output: false (they are different objects) } }
finalize():finalize()মেথডটি একটি অবজেক্ট গার্বেজ কালেকশনের আগে কল হয়। এটি শুধুমাত্র গার্বেজ কালেকশন প্রক্রিয়া দ্বারা ব্যবহৃত হয় এবং সাধারণত এটি override করা হয় না।
Object ক্লাসের প্রধান ব্যবহার:
- Object Comparisons:
equals()এবংhashCode()ব্যবহার করে অবজেক্টগুলির সমানতা যাচাই করা এবং তাদের হ্যাশ কোড তৈরি করা। - Object Cloning:
clone()ব্যবহার করে অবজেক্টের শ্যালো কপি তৈরি করা। - Object Lifecycle Management:
finalize()ব্যবহার করে অবজেক্টের জীবনের শেষ পর্যায়ে প্রয়োজনীয় সম্পদ মুক্ত করা। - Object String Representation:
toString()ব্যবহার করে অবজেক্টের বর্ণনা তৈরি করা।
Object ক্লাস হল Java-এর সবচেয়ে গুরুত্বপূর্ণ ক্লাস, কারণ এটি Java-তে সমস্ত ক্লাসের জন্য বেস ক্লাস হিসেবে কাজ করে এবং অনেক গুরুত্বপূর্ণ ফাংশন সরবরাহ করে, যেমন toString(), equals(), hashCode(), clone(), ইত্যাদি। এগুলি Java অ্যাপ্লিকেশনগুলির মধ্যে অবজেক্টের সঠিক ব্যবহারের জন্য অপরিহার্য এবং প্রোগ্রামারদের তাদের ক্লাসগুলি কাস্টমাইজ করতে এবং ডেটা সঠিকভাবে পরিচালনা করতে সহায়তা করে।
java.lang প্যাকেজ Java এর একটি বিল্ট-ইন প্যাকেজ যা Java অ্যাপ্লিকেশনের জন্য অত্যন্ত গুরুত্বপূর্ণ ক্লাস এবং ইন্টারফেস সরবরাহ করে। এটি এমন কিছু গুরুত্বপূর্ণ ক্লাস ধারণ করে, যা অন্যান্য প্যাকেজ বা লাইব্রেরি থেকে সহজেই অ্যাক্সেস করা যায় এবং সেগুলি Java প্রোগ্রামগুলির জন্য অত্যাবশ্যক। এই প্যাকেজে থাকা অনেক ক্লাস এমনভাবে ডিজাইন করা হয়েছে, যাতে এগুলির ব্যবহারের জন্য কোনো নির্দিষ্ট ইনপোর্ট স্টেটমেন্টের প্রয়োজন পড়ে না।
এটির মধ্যে থাকা Object ক্লাস Java এর সবচেয়ে মৌলিক এবং গুরুত্বপূর্ণ ক্লাস। এটি Java ক্লাস হায়ারার্কি এর মূল ভিত্তি, কারণ সমস্ত ক্লাস সরাসরি বা পরোক্ষভাবে এই ক্লাস থেকে উত্তরাধিকার সূত্রে পায়।
Object ক্লাসের গুরুত্ব:
- Java ক্লাস হায়ারার্কির মূল ভিত্তি:
Objectক্লাস Java ক্লাস হায়ারার্কির মূল এবং এটি Java প্রোগ্রামের সব ক্লাসের সুপারক্লাস (superclass)। অর্থাৎ, Java-তে যে কোনো ক্লাসেরই এক বা একাধিক সুপারক্লাস থাকে, কিন্তু প্রত্যেক ক্লাসের একটি সর্বোচ্চ সুপারক্লাসObjectক্লাস, যা প্রত্যেক Java ক্লাসের অপ্রত্যক্ষ পূর্বসূরি (ancestor)।উদাহরণস্বরূপ, আপনি যদি একটি নতুন ক্লাস তৈরি করেন, যেমন:
class MyClass extends SomeOtherClass { // Your class code here }তাহলে
MyClassএর সুপারক্লাস হবেSomeOtherClassএবং পরোক্ষভাবে এর সুপারক্লাস হবেObject।
- Object ক্লাসের গুরুত্বপূর্ণ মেথড:
Objectক্লাসে কিছু অত্যন্ত গুরুত্বপূর্ণ মেথড রয়েছে, যা সব ক্লাসে উপলব্ধ থাকে (কারণ তারাObjectথেকে উত্তরাধিকারসূত্রে পাওয়া যায়)। কিছু গুরুত্বপূর্ণ মেথড হল:toString()মেথড:- এই মেথডটি সব ক্লাসে ডিফল্টভাবে উপলব্ধ থাকে এবং এটি একটি স্ট্রিং রিপ্রেজেন্টেশন প্রদান করে। আপনি যদি নিজের ক্লাসে
toString()মেথড ওভাররাইড করেন, তাহলে তা আপনার অবজেক্টের একটি মানব-পাঠযোগ্য রিপ্রেজেন্টেশন প্রদান করবে। উদাহরণ:
class MyClass { int id; String name; MyClass(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "MyClass{id=" + id + ", name='" + name + "'}"; } } public class Main { public static void main(String[] args) { MyClass obj = new MyClass(1, "John"); System.out.println(obj); // Output: MyClass{id=1, name='John'} } }
- এই মেথডটি সব ক্লাসে ডিফল্টভাবে উপলব্ধ থাকে এবং এটি একটি স্ট্রিং রিপ্রেজেন্টেশন প্রদান করে। আপনি যদি নিজের ক্লাসে
equals()মেথড:equals()মেথডটি অবজেক্টগুলির সমতা পরীক্ষা করতে ব্যবহৃত হয়। ডিফল্টভাবে,Objectক্লাসেরequals()মেথড কেবল অবজেক্টের রেফারেন্সের তুলনা করে, কিন্তু আপনি আপনার ক্লাসে এটি ওভাররাইড করে কন্টেন্ট সমতার তুলনা করতে পারেন।উদাহরণ:
class Person { String name; Person(String name) { this.name = name; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; return name.equals(person.name); } } public class Main { public static void main(String[] args) { Person p1 = new Person("Alice"); Person p2 = new Person("Alice"); System.out.println(p1.equals(p2)); // Output: true } }
hashCode()মেথড:hashCode()মেথড অবজেক্টের একটি হ্যাশ কোড প্রদান করে, যা সাধারণতequals()মেথডের সাথে সম্পর্কিত থাকে। যখন আপনিequals()মেথডকে ওভাররাইড করেন, তখন আপনি সাধারণতhashCode()মেথডও ওভাররাইড করেন, যাতে অবজেক্টগুলির মধ্যে সঠিক সমতা এবং হ্যাশিং কাজ করে।উদাহরণ:
@Override public int hashCode() { return name.hashCode(); }
getClass()মেথড:getClass()মেথডটি অবজেক্টেরClassঅবজেক্ট প্রদান করে, যা ক্লাসের রuntime টাইপ সম্পর্কে তথ্য দেয়। এটি আপনাকে ক্লাসের তথ্য (যেমন ক্লাসের নাম) জানাতে সাহায্য করে।উদাহরণ:
MyClass obj = new MyClass(1, "John"); System.out.println(obj.getClass().getName()); // Output: MyClass
clone()মেথড:clone()মেথড একটি শ্যালো কপি তৈরি করতে ব্যবহৃত হয়। এটি সাধারণতCloneableইন্টারফেস ইমপ্লিমেন্ট করার জন্য ব্যবহৃত হয়, যাতে আপনি একটি অবজেক্টের কপি তৈরি করতে পারেন।উদাহরণ:
class MyClass implements Cloneable { int id; MyClass(int id) { this.id = id; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
- উত্তরাধিকার (Inheritance):
- যেহেতু সব Java ক্লাসই
Objectক্লাস থেকে উত্তরাধিকার পায়,Objectক্লাস সব ক্লাসের জন্য একটি সাধারণ বেস ক্লাস হিসাবে কাজ করে। এর মাধ্যমে, যেকোনো ক্লাসObjectক্লাসের মেথডগুলি হেরিট করে।
- যেহেতু সব Java ক্লাসই
- জেনেরিক্সের সাথে ব্যবহার:
Objectক্লাস Java-এ জেনেরিক্সের ব্যবহারকে সাধারণত সমর্থন করে।Objectক্লাসের অবজেক্ট যেকোনো টাইপের ডেটা ধারণ করতে সক্ষম, তাই এটি একটি উপযুক্ত টাইপ বেস ক্লাস হিসাবে ব্যবহৃত হয়।
Object ক্লাসের প্রধান মেথডগুলি:
public boolean equals(Object obj)public int hashCode()public String toString()protected Object clone() throws CloneNotSupportedExceptionpublic Class<?> getClass()public final void notify()public final void notifyAll()public final void wait()public final void wait(long timeout)
Object ক্লাস হল Java-এর সবচেয়ে মৌলিক ক্লাস, যা সব ক্লাসের জন্য একটি সুপারক্লাস। এটি Java ক্লাস হায়ারার্কির ভিত্তি, এবং এর মেথডগুলি (যেমন equals(), hashCode(), toString()) অনেক ক্ষেত্রে কোড রিইউজ এবং ডিবাগিংয়ে সাহায্য করে। Object ক্লাসের বৈশিষ্ট্যগুলি সকল Java ক্লাসে কার্যকরী হয়, তাই এটি Java প্রোগ্রামিং ভাষার একটি অপরিহার্য অংশ।
Java.lang প্যাকেজ একটি প্রাথমিক এবং অপরিহার্য প্যাকেজ যা Java প্রোগ্রামিং ভাষার সবচেয়ে মৌলিক ক্লাসগুলির একটি সেট সরবরাহ করে। এর মধ্যে অন্যতম হল Object ক্লাস, যা সমস্ত ক্লাসের জন্য সুপারক্লাস হিসাবে কাজ করে। Object ক্লাসের কিছু গুরুত্বপূর্ণ মেথড হল equals(), hashCode(), এবং toString()।
এগুলির কাজ এবং ব্যবহার বিস্তারিতভাবে ব্যাখ্যা করা হলো:
1. equals() মেথড:
equals() মেথড দুটি অবজেক্টের সমানতা পরীক্ষা করতে ব্যবহৃত হয়। ডিফল্টভাবে, Object ক্লাসের equals() মেথডটি অবজেক্টের রেফারেন্স ঠিকানার তুলনা করে, অর্থাৎ এটি referential equality যাচাই করে, কিন্তু অনেক সময় এটি কাস্টম ক্লাসে value equality যাচাই করার জন্য ওভাররাইড করা হয়।
ডিফল্ট equals() মেথড:
public boolean equals(Object obj) {
return (this == obj); // Check if both references point to the same object
}
Custom equals() মেথড:
যখন আপনি নিজের equals() মেথড লিখবেন, তখন সাধারণত এই মেথডটি অবজেক্টের value equality যাচাই করবে (অর্থাৎ, অবজেক্টগুলির ভিতরের মান সমান কিনা তা পরীক্ষা করবে)।
উদাহরণ:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("John", 25);
Person p2 = new Person("John", 25);
System.out.println(p1.equals(p2)); // true, because both have the same name and age
}
}
2. hashCode() মেথড:
hashCode() মেথড অবজেক্টের একটি unique integer code প্রদান করে যা সাধারণত অবজেক্টের memory address বা অবজেক্টের ভ্যালু অনুযায়ী নির্ধারিত হয়। যদি আপনি equals() মেথডকে কাস্টমাইজ করেন, তবে আপনাকে hashCode() মেথডও কাস্টমাইজ করতে হবে যাতে contract ঠিক থাকে।
hashCode() মেথডের কনট্রাক্ট:
- যদি দুটি অবজেক্ট সমান হয় (যেমন
equals()মেথডে যাচাই করা হয়), তবে তাদেরhashCode()মানও সমান হতে হবে। hashCode()-এর মান কখনও পরিবর্তন করা উচিত নয় (যতক্ষণ অবজেক্টের বৈশিষ্ট্য না বদলানো হয়)।
উদাহরণ:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age); // Generate hashcode based on name and age
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("John", 25);
Person p2 = new Person("John", 25);
System.out.println(p1.hashCode() == p2.hashCode()); // true, because hashcodes are equal
}
}
3. toString() মেথড:
toString() মেথড অবজেক্টের string representation প্রদান করে। Object ক্লাসের ডিফল্ট toString() মেথডটি অবজেক্টের memory address প্রদান করে, তবে এটি প্রায়ই কাস্টম ক্লাসে human-readable string আকারে অবজেক্টের মান প্রদর্শন করার জন্য ওভাররাইড করা হয়।
ডিফল্ট toString() মেথড:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Custom toString() মেথড:
কাস্টম ক্লাসে toString() মেথডটি অবজেক্টের প্রাসঙ্গিক মান প্রদর্শন করার জন্য ওভাররাইড করা হয়।
উদাহরণ:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("John", 25);
System.out.println(p.toString()); // Person{name='John', age=25}
}
}
equals(), hashCode(), এবং toString() এর মধ্যে সম্পর্ক:
equals()এবংhashCode():hashCode()মেথডটিequals()মেথডের সাথে সম্পর্কিত। যদি দুটি অবজেক্ট সমান হয় (যেequals()-এর মাধ্যমে যাচাই করা হয়), তবে তাদেরhashCode()একই হতে হবে।- এই সম্পর্কের মাধ্যমে,
hashCode()মেথডটি Collections (যেমনHashMap,HashSetইত্যাদি) এর মধ্যে দ্রুত সার্চিং, ইনসার্ট এবং ডিলিট অপারেশন পরিচালনা করতে সহায়তা করে।
toString():toString()মেথডটি শুধুমাত্র অবজেক্টের human-readable রূপ সরবরাহ করে। এটি ডিবাগিং, লগিং, এবং প্রদর্শনের জন্য কার্যকর।
equals(): অবজেক্টগুলির মান তুলনা করার জন্য ব্যবহৃত হয়। এটি value equality যাচাই করে।hashCode(): এটি অবজেক্টের ইউনিক আইডেন্টিফায়ার তৈরি করে এবং hashing-based ডেটা structures (যেমনHashMap,HashSet) এর মধ্যে সঠিকভাবে কাজ করতে সাহায্য করে।toString(): অবজেক্টের একটি পাঠযোগ্য string representation প্রদান করে, যা ডিবাগিং বা ইউজার ইন্টারফেসে প্রদর্শনের জন্য উপকারী।
এই তিনটি মেথডই Object ক্লাস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত, এবং এই মেথডগুলিকে প্রায়শই কাস্টম ক্লাসে ওভাররাইড করা হয় যাতে সঠিক value equality, hashing এবং readable output পাওয়া যায়।
Java.lang প্যাকেজ Java প্রোগ্রামিং ল্যাঙ্গুয়েজের একটি গুরুত্বপূর্ণ প্যাকেজ, যা খুবই সাধারণ এবং প্রয়োজনীয় ক্লাস এবং ইন্টারফেস অন্তর্ভুক্ত করে। এই প্যাকেজে থাকা clone() মেথড এবং Cloneable ইন্টারফেস Java-তে অবজেক্ট ক্লোনিংয়ের জন্য ব্যবহৃত হয়।
clone() মেথড:
clone() মেথড হল Object ক্লাসের একটি মেথড যা একটি অবজেক্টের শ্যালো কপি (shallow copy) তৈরি করে। যখন আপনি একটি অবজেক্ট ক্লোন করতে চান, তখন clone() মেথডটি সেই অবজেক্টের একটি নতুন কপি তৈরি করে, যার প্যাটার্ন হলো মূল অবজেক্টের মত। এটি Shallow Copy তৈরি করে, অর্থাৎ শুধুমাত্র অবজেক্টের রেফারেন্স কপি করা হয়, বাস্তব কনটেন্ট কপি হয় না (যেমন এক্সটেনডেড অবজেক্ট বা নেস্টেড অবজেক্টের ক্ষেত্রে)।
clone() মেথডের ব্যবহার:
- Shallow Copy:
clone()শুধুমাত্র অবজেক্টের প্রথম স্তরের কপি তৈরি করে। এটি যদি একটি অবজেক্টে আরেকটি অবজেক্টের রেফারেন্স থাকে, তবে ক্লোন করা অবজেক্টে ঐ রেফারেন্সের মানও কপি হবে, তবে অবজেক্টের ভেতরের ডেটার কপি হবে না। - Override Required:
clone()মেথডটিObjectক্লাসে ডিফাইন করা হলেও, এটি শুধুমাত্র তখন কাজ করে যখন অবজেক্টের ক্লাসCloneableইন্টারফেসটি ইমপ্লিমেন্ট করে।
clone() মেথডের সিঙ্কট্যাক্স:
protected Object clone() throws CloneNotSupportedException
- protected: এটি
protectedহওয়ায়, ক্লাসগুলো নিজস্ব ক্লোনিং কার্যকলাপের জন্য এটি ব্যবহার করতে পারে, তবে বাইরের ক্লাসে সরাসরি অ্যাক্সেস করা যাবে না। - throws CloneNotSupportedException: যদি কোনো ক্লাস
Cloneableইন্টারফেস ইমপ্লিমেন্ট না করে, তাহলে এই মেথডCloneNotSupportedExceptionছুঁড়ে দেয়।
Cloneable Interface:
Cloneable একটি মার্কার ইন্টারফেস, অর্থাৎ এটি কোনও মেথড ডিফাইন করে না। এর লক্ষ্য হল Java এর ক্লাসগুলোকে ক্লোনযোগ্য (cloneable) হিসেবে চিহ্নিত করা। যদি একটি ক্লাস Cloneable ইন্টারফেস ইমপ্লিমেন্ট করে, তবে ঐ ক্লাসের অবজেক্ট ক্লোন করা যাবে। যদি ক্লাসটি Cloneable ইন্টারফেস ইমপ্লিমেন্ট না করে এবং clone() মেথড কল করা হয়, তবে CloneNotSupportedException আছড়ে পড়বে।
Cloneable ইন্টারফেস ব্যবহার:
Cloneableইন্টারফেস এক ধরনের চুক্তি বা সিগন্যাল যা বলে দেয় যে একটি ক্লাসের অবজেক্ট ক্লোন করা যাবে। এটি ক্লাসের ভিতরে কোনো মেথড ডিফাইন না করলেও শুধুমাত্র একটি চিহ্ন হিসেবে কাজ করে।
clone() মেথড এবং Cloneable Interface এর উদাহরণ:
class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter methods
public String getName() {
return name;
}
public int getAge() {
return age;
}
// Override the clone method
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Call the clone method of Object class
}
}
public class CloneExample {
public static void main(String[] args) {
try {
// Create an object
Person person1 = new Person("John", 25);
// Clone the object
Person person2 = (Person) person1.clone();
System.out.println("Original Person: " + person1.getName() + ", " + person1.getAge());
System.out.println("Cloned Person: " + person2.getName() + ", " + person2.getAge());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
ব্যাখ্যা:
Personক্লাসটিCloneableইন্টারফেস ইমপ্লিমেন্ট করেছে, যার ফলেclone()মেথডটি সফলভাবে কাজ করতে পারবে।clone()মেথডটিsuper.clone()কল করছে, যা মূলObjectক্লাসেরclone()মেথডকে ব্যবহার করে অবজেক্টের কপি তৈরি করে।person1এর কপি তৈরি করেperson2কে প্রদান করা হয়েছে, এবং পরে তাদের নাম ও বয়স প্রদর্শিত হয়েছে।
আউটপুট:
Original Person: John, 25
Cloned Person: John, 25
Shallow Copy বনাম Deep Copy:
- Shallow Copy:
clone()মেথডটি সাধারণত শ্যালো কপি তৈরি করে। অর্থাৎ যদি কোনো অবজেক্টে অন্য অবজেক্টের রেফারেন্স থাকে, তবে ক্লোনকৃত অবজেক্টে সেই রেফারেন্সের কপি থাকে, কিন্তু ভ্যালুগুলোর কপি থাকে না। - Deep Copy: যদি আপনি পুরো অবজেক্টের কপি করতে চান (অর্থাৎ, ঐ অবজেক্টের ভিতরের সব রেফারেন্সে গিয়েও কপি করতে চান), তাহলে আপনাকে deep cloning এর জন্য ম্যানুয়ালি কোড লিখতে হবে।
Shallow Copy Example:
class Car implements Cloneable {
private String model;
private Engine engine;
public Car(String model, Engine engine) {
this.model = model;
this.engine = engine;
}
public String getModel() {
return model;
}
public Engine getEngine() {
return engine;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Shallow copy
}
}
class Engine {
private String type;
public Engine(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
public class ShallowCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Engine engine = new Engine("V8");
Car car1 = new Car("Toyota", engine);
Car car2 = (Car) car1.clone();
System.out.println(car1.getEngine().getType()); // Output: V8
System.out.println(car2.getEngine().getType()); // Output: V8
// Modifying the engine of car2 will affect car1 as well because both refer to the same Engine object
car2.getEngine().getType();
System.out.println(car1.getEngine().getType()); // Output: modified value of engine type
}
}
এখানে Car ক্লাসের ক্লোনিং একটি shallow copy তৈরি করবে, এবং Engine অবজেক্টে পরিবর্তন করলে তা মূল car1 অবজেক্টকেও প্রভাবিত করবে কারণ তারা একই Engine অবজেক্টের রেফারেন্স শেয়ার করছে।
clone()মেথড একটি অবজেক্টের শ্যালো কপি তৈরি করতে ব্যবহৃত হয়।Cloneableএকটি মার্কার ইন্টারফেস যা Java অবজেক্ট ক্লোনিং সক্ষম করে।- যদি কোনো ক্লাস
Cloneableইন্টারফেস ইমপ্লিমেন্ট না করে, তাহলেclone()মেথড কল করলেCloneNotSupportedExceptionঅ্যাক্সেপশন ছুঁড়ে দেওয়া হবে।
Object ক্লাস হল Java এর সবচেয়ে মৌলিক ক্লাস এবং এটি সব ক্লাসের জন্য একটি সুপারক্লাস (superclass) হিসেবে কাজ করে। এটি java.lang প্যাকেজের একটি অংশ এবং Java এর সমস্ত ক্লাসই এটি ইনহেরিট করে। Object ক্লাসের কিছু গুরুত্বপূর্ণ মেথড রয়েছে যা অ্যাপ্লিকেশন ডেভেলপমেন্টে বিভিন্ন পরিস্থিতিতে ব্যবহৃত হয়। এই মেথডগুলো হল:
- getClass()
- notify()
- wait()
- finalize()
1. getClass() Method
getClass() মেথডটি একটি অবজেক্টের ক্লাসের ইনফরমেশন প্রদান করে। এটি একটি Class অবজেক্ট রিটার্ন করে, যা সেই অবজেক্টের ক্লাসের তথ্য ধারণ করে।
সিগনেচার:
public final Class<?> getClass()
ব্যাখ্যা:
- এই মেথডটি একটি অবজেক্টের রানটাইম ক্লাসের তথ্য নিয়ে আসে।
- এটি
Objectক্লাসে ডিফাইন করা হওয়ায়, সব Java ক্লাসেই এই মেথডটি ব্যবহৃত হতে পারে। Classঅবজেক্ট ব্যবহার করে আপনি ক্লাসের নাম, প্যাকেজ, সুপারক্লাস ইত্যাদি জানতে পারেন।
উদাহরণ:
public class Example {
public static void main(String[] args) {
String str = "Hello";
Class<?> cls = str.getClass(); // getClass() মেথড ব্যবহার
System.out.println("Class Name: " + cls.getName());
}
}
Output:
Class Name: java.lang.String
2. notify() Method
notify() মেথডটি মাল্টিথ্রেডিং প্রোগ্রামে ব্যবহৃত হয়। এটি একটি থ্রেডকে wait অবস্থায় থেকে জাগ্রত (notify) করে। যখন একটি থ্রেড কোন নির্দিষ্ট অবজেক্টে synchronized block বা method এ থাকে এবং অন্য থ্রেড wait() ব্যবহার করে, তখন notify() থ্রেডটির কাজ আবার শুরু করতে সহায়তা করে।
সিগনেচার:
public final void notify()
ব্যাখ্যা:
notify()একটি থ্রেডকে জাগ্রত করে যা synchronized ব্লকে wait() অবস্থায় ছিল।- এটি শুধুমাত্র synchronized ব্লক অথবা মেথডের মধ্যে কল করা যায়।
উদাহরণ:
class Example {
synchronized void method1() {
System.out.println("Thread1 is running");
notify(); // Notify অন্য থ্রেডকে
}
synchronized void method2() throws InterruptedException {
wait(); // Wait করে থাকবে
System.out.println("Thread2 is running");
}
}
public class NotifyExample {
public static void main(String[] args) throws InterruptedException {
Example obj = new Example();
Thread t1 = new Thread(() -> {
try {
obj.method1();
} catch (Exception e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
obj.method2();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
}
3. wait() Method
wait() মেথডটি একইভাবে মাল্টিথ্রেডিং প্রোগ্রামে ব্যবহৃত হয়। এটি থ্রেডকে synchronized ব্লকের মধ্যে wait অবস্থায় রাখে, যাতে অন্য কোনো থ্রেড তার কাজ সম্পন্ন করার পর থ্রেডটি আবার চালু হয়। wait() মেথড থ্রেডকে কম্পলিট না হওয়া পর্যন্ত অবরুদ্ধ করে রাখে।
সিগনেচার:
public final void wait() throws InterruptedException
ব্যাখ্যা:
wait()মেথডটি একটি থ্রেডকে ওই অবজেক্টের উপর wait অবস্থায় রাখে যতক্ষণ না অন্য কোনো থ্রেড তার কাজ শেষ করে notify() করে না।- এই মেথডটি শুধুমাত্র synchronized ব্লকের মধ্যে কাজ করে।
উদাহরণ:
class Example {
synchronized void method1() {
try {
System.out.println("Thread1 is running");
wait(); // Wait অবস্থায় চলে যাবে
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void method2() {
System.out.println("Thread2 is running");
notify(); // Notify থ্রেড 1 কে
}
}
public class WaitExample {
public static void main(String[] args) throws InterruptedException {
Example obj = new Example();
Thread t1 = new Thread(() -> {
try {
obj.method1();
} catch (Exception e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> obj.method2());
t1.start();
t2.start();
}
}
4. finalize() Method
finalize() মেথডটি Java-তে একটি অবজেক্ট garbage collection এর আগে কল করতে পারে। এটি অবজেক্টের ডেস্ট্রাকশন বা ক্লিনআপ অপারেশন সম্পন্ন করার জন্য ব্যবহৃত হয়। তবে, এটি deprecated হতে পারে এবং এটি মূলত গার্বেজ কালেকশন ব্যবস্থার সাথে সম্পর্কিত।
সিগনেচার:
protected void finalize() throws Throwable
ব্যাখ্যা:
finalize()মেথড সাধারণত একটি অবজেক্ট গার্বেজ কালেকশন দ্বারা সরানোর আগে কল করা হয়।finalize()মেথডটি কখন কল হবে তা পূর্বানুমান করা সম্ভব নয়, কারণ এটি গার্বেজ কালেকশন মেকানিজমের উপর নির্ভরশীল।
উদাহরণ:
class MyClass {
protected void finalize() throws Throwable {
System.out.println("Finalizing object");
super.finalize();
}
}
public class FinalizeExample {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj = null; // এখন অবজেক্টটি null, এবং এটি গার্বেজ কালেক্টর দ্বারা মুছে ফেলা হবে।
System.gc(); // গার্বেজ কালেকশন কল করা
}
}
Output:
Finalizing object
Java এর Object ক্লাসের এই মেথডগুলি মাল্টিথ্রেডিং এবং মেমরি ম্যানেজমেন্টে অত্যন্ত গুরুত্বপূর্ণ ভূমিকা পালন করে:
getClass()— অবজেক্টের ক্লাসের ইনফরমেশন পাওয়া যায়।notify()— থ্রেডকে জাগিয়ে তোলে যা wait() অবস্থায় রয়েছে।wait()— থ্রেডকে wait() অবস্থায় রাখে যতক্ষণ না অন্য থ্রেড তাকে notify() করে।finalize()— অবজেক্ট গার্বেজ কালেকশনের আগে কিছু ক্লিনআপ কাজ করতে ব্যবহৃত হয়।
এই মেথডগুলির মাধ্যমে আপনি কোডে থ্রেড সমন্বয় এবং মেমরি ক্লিনআপ করতে সক্ষম হবেন।
Read more